/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is JsWs.
 *
 * The Initial Developer of the Original Code is
 * Chris Winberry.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */

/**
 * @class Represents a module loaded by JsWs
 * @constructor
 * @param {String} id The module's ID (not extension ID)
 * @param {nsIPrefBranch} prefBranch (optional) Preference branch to read module settings from
 * @exception ExParamError
 */
function Module (id, prefBranch) {
	if (prefBranch != null && !(prefBranch instanceof Ci.nsIPrefBranch))
		throw(new ExParamError("Parameter \"prefBranch\" is of an unexpected type (" + typeof prefBranch + ")", 0, null, arguments));

	/**
	 * Module identifier
	 * @type String
	 */
	this.id = id;
	/**
	 * Path to the extension hosting the module
	 * @type String
	 */
	this.extensionPath = null;
	/**
	 * Path, relative to {@link #extensionPath} where the module's
	 * content is located
	 * @type String
	 */
	this.contentPath = null;
	/**
	 * Path to where the module's document root should be
	 * @type VirtualPath
	 */
	this.virtualPath = new VirtualPath("/");
	/**
	 * Display name of the module
	 * @type String
	 */
	this.name = id;
	/**
	 * Description of the module
	 * @type String
	 */
	this.description = "Module: " + this.id;
	/**
	 * Initialization page for the module
	 * @type String
	 */
	this.initPage = null;
	/**
	 * Start/Home page for the module
	 * @type String
	 */
	this.startPage = null;
	/**
	 * Custom page handler for requests in the module
	 * @type String
	 */
	this.handler = null;

	if (prefBranch) {
		var children = prefBranch.getChildList("", {});
		for (var i = 0; i < children.length; i++)
			this.setProperty(children[i], prefBranch.getCharPref(children[i]));
	}
}

/**
 * Set a module property. Maps preference name constants to
 *  actual properties to make loading from prefs easier.
 * @param {String} name Name of the preference to set
 * @param {String} value Value to set the property to
 */
Module.prototype.setProperty = function (name, value) {
	switch (name) {
		case JSWS_MODULES_IDKEY :
			this.id = value;
			var extManager = Cc["@mozilla.org/extensions/manager;1"]
				.createInstance(Ci.nsIExtensionManager);
			this.extensionPath = extManager
				.getInstallLocation(this.id)
				.getItemLocation(this.id)
				.path;
			break;
		case JSWS_MODULES_NAMEKEY :
			this.name = value;
			break;
		case JSWS_MODULES_EXTENSIONPATHKEY :
			this.extensionPath = value;
			break;
		case JSWS_MODULES_CONTENTPATHKEY :
			this.contentPath = value;
			break;
		case JSWS_MODULES_VIRTUALPATHKEY :
			this.virtualPath = value;
			break;
		case JSWS_MODULES_HANDLERKEY :
			this.handler = value;
			break;
		case JSWS_MODULES_STARTPAGEKEY :
			this.startPage = value;
			break;
		case JSWS_MODULES_DESCRIPTIONKEY :
			this.description = value;
			break;
		case JSWS_MODULES_INITPAGEKEY :
			this.initPage = value;
			break;
	}
}

/**
 * Scans a preference branch for registered modules. Found modules
 *  are instanced and returned in an array.
 * @param {String} prefBase Location in preferences to scan for modules
 * @returns An array of found modules
 * $type {Module[]}
 */
Module.loadFromPrefs = function (prefBase) {
	var modules = new Array();
	try {
		var extManager = Cc["@mozilla.org/extensions/manager;1"]
			.createInstance(Ci.nsIExtensionManager);
		var prefSvc = Cc["@mozilla.org/preferences-service;1"]
			.getService(Ci.nsIPrefService);
		var prefBranch = prefSvc.getBranch(prefBase);
		var children = prefBranch.getChildList("", {});
		for (var i = 0; i < children.length; i++) {
			var module = children[i].split('.')[0];
			if (!modules[module])
				modules[module] = new Module(module, prefSvc.getBranch(prefBase + module + "."));
		}
	} catch (e) { }

	return(modules);
}
